home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i051: Network News Transfer Protocol, version 1.5, Part05/09
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Phil Lapsley <phil@ucbvax.berkeley.edu>
- Posting-number: Volume 14, Issue 51
- Archive-name: nntp1.5/part05
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 9)."
- # Wrapped by rsalz@fig.bbn.com on Tue Apr 19 18:16:43 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./README'\"
- else
- echo shar: Extracting \"'./README'\" \(6865 characters\)
- sed "s/^X//" >'./README' <<'END_OF_FILE'
- NNTP README January 23, 1988 For version 1.5 NNTP package
- X
- X[See the file CHANGES to see differences between this version and
- older versions.]
- X
- INTRODUCTION
- X
- X This package contains everything (well, most of it, I hope) that
- you'll need to implement a remote news server running the NNTP protocol.
- X
- X A brief tour of the directories and their programs:
- X
- X server Source for the NNTP news server daemon.
- X
- X rrnpatches Patches to rn #39 to allow remote news reading.
- X
- X inews A "mini-inews" written by Steven Grady
- X <grady@postgres.berkeley.edu> which allows
- X remote posting without changing much else.
- X
- X xmit An active transmission client for transferring
- X news, written by Erik Fair; see note below.
- X
- X common Common stuff (response codes, configuration info,
- X and some client library routines) for the
- X the news server and the clients. The "conf.h"
- X file here needs to be edited to reflect
- X the peculiarities of your system.
- X
- X support Some support files and scripts.
- X
- X doc Documentation on the server, including manual
- X pages. Manual pages for rrn are in rrn/.
- X
- X xfer A passive reception client which uses the
- X NEWNEWS command to retrieve news from a remote
- X server. Written by Brian Kantor, this software
- X is UNSUPPORTED.
- X
- X Each directory has associated with it a README file.
- This file will try to give enough information for you to get things
- running and installed, but the README in each directory has more
- details for each subset of the NNTP package. You may also want to print
- a copy of doc/rfc977, which describes the NNTP protocol.
- X
- INTRODUCTION TO NNTP INSTALLATION
- X
- X First, figure out what you are trying to do (this is good
- advice under most circumstances, and it is especially apropos here).
- NNTP can be used for two things: (1) Remote news reading, where news
- is stored on one machine and read from remote machines across a
- high-speed local area network such as Ethernet, and (2) News transfer,
- where news is transmitted to NNTP servers on remote machines over
- either local or long-haul networks.
- X
- X NNTP "server" machines are machines that have a full installation
- of USENET news on them. An NNTP process, the "server", allows remote
- sites to connect to the server machine and read or transfer news.
- The server machine DOES NOT NEED "reader client" software such as
- X"rrn". It MAY NEED "transmission client" software such as "nntpxmit"
- if you want to use NNTP to transfer news.
- X
- X NNTP "client" machines do not have a full installation of USENET
- news on them. They get their news from an NNTP server machine across
- the network. They DO have NNTP "reader clients" such as "rrn" installed
- on them.
- X
- X In summary,
- X
- X >>> A full client installation of NNTP requires the following
- X files (suitable for rdist, assuming standard directories):
- X
- NEWS = ( /usr/local/{Pnews,Rnmail,inews,rn,rrn,newsetup,newsgroups,lib/rn}
- X /usr/man/catl/{Pnews,Rnmail,rn,newsetup,newsgroups}.1 )
- X
- X You DO NOT need any of the normal news junk (e.g.,
- X /usr/lib/news, postnews, checknews, readnews) on CLIENT
- X systems.
- X
- X You DO need these on SERVER systems.
- X
- X An important note:
- X
- X The NNTP server assumes that the history file format
- X is 2.11 or 2.10.3; therefore you need 2.11 news on your
- X server machine.
- X
- X >>>>> Get 2.11 news if you don't have it.
- X
- GENERAL INSTALLATION
- X
- X Time for a general and cohesive Plan:
- X
- X Regardless of whether you are making a server or a client NNTP
- setup, you will have to edit common/conf.h to reflect your system's
- setup. So,
- X
- X 1. Look at common/README. This will explain the stuff
- X needs to be tailored for your system in common/conf.h.
- X Make the necessary changes to reflect your system.
- X
- X If you are running with System V or Excelan TCP/IP,
- X please read Stan Barber's instructions in common/README.SYSV
- X
- X If you have an HPUX machine, please read common/README.HPUX
- X
- X Now, at this point, what you do depends on whether you are
- installing a server system or a client system.
- X
- SERVER INSTALLATION
- X
- X 2. Type "make server" in this directory.
- X
- X 3. Type "make install_server" in this directory.
- X
- CLIENT INSTALLATION
- X
- X 2. You must configure "rrn", the remote newsreading client.
- X cd into "rrnpatches", and read README_RRN. This will explain
- X how to apply the patches supplied to turn rn #39 into rrn #39.
- X
- X 3. Type "make client" in this directory.
- X
- X 4. Type "make install_client" in this directory.
- X
- IF YOU HAVE PROBLEMS
- X
- X You can get to me via electronic mail at the following addresses:
- X
- X Internet: phil@ucbvax.berkeley.edu
- X UUCP: ...!ucbvax!phil
- X Telephone (home): (415) 848-8409
- X Telephone (work): (415) 642-7447
- X
- X I'm very interested in learning what hacks need to be made to
- nntpd to get it to work on various systems, and certainly, if there are
- outright bugs, please let me know. Bug reports and fixes for nntp are
- posted to the newsgroup "news.software.nntp". Announcements of new
- versions of nntp software are posted there too.
- X
- X I'll support bugs caused by my additions/hacks to turn "rn" into
- X"rrn" (hopefully Larry Wall will be supporting this soon...) but please
- don't send me reports about things that were already in rn itself.
- Also, if you add features to rrn, I probably am not interested in
- supporting them unless they are really necessary; every change I make
- to rrn is something that I have to hack into future releases of rn, so
- the fewer changes, the better.
- X
- ACKNOWLEDGEMENTS
- X
- X I'd like to thank the various people who both inspired and helped
- to make NNTP a reality: Erik Fair, whose criticism and suggestions
- helped mold NNTP (and who wrote the active transmission client); Brian
- Kantor, who really got me motivated enough to finish the thing, and
- whose work on the RFC was *tremendous*; Steven Grady, who wrote the
- inews interface (and wasted countless hours only to have his work
- dashed periodically...); Mike Meyer, who beta tested the software and
- pointed out numerous problems; Bob Henry, who let me have the resources
- so that it got done; Peter Yee, who repeated enough good ideas to get
- me to include them; all the folks who had patience with me and didn't
- go off and write this themselves (jsq, you listening? My thanks.);
- Chuq von Rospach and the members of lan-news; Gene Spafford for
- eliminating having to include 1 MB of source to rn by a set of patches;
- Matt Thomas for adding support for DECNET; Stan Barber for adding
- System V/Excelan support and putting up with my sloth; the kind folks
- who beta tested version 1.4 and put up with stupid bugs and provided
- helpful feedback, notably Craig Leres, Matt Thomas, Wengyik Yeong, and
- Stan Barber; all the individuals who have reported bugs or suggested
- improvements (see CHANGES for a list); and probably many other people
- I've neglected to mention. My thanks to all.
- X
- X Phil Lapsley
- X 26 February 1988
- END_OF_FILE
- if test 6865 -ne `wc -c <'./README'`; then
- echo shar: \"'./README'\" unpacked with wrong size!
- fi
- # end of './README'
- fi
- if test -f './rrnpatches/Configure.pat' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rrnpatches/Configure.pat'\"
- else
- echo shar: Extracting \"'./rrnpatches/Configure.pat'\" \(6499 characters\)
- sed "s/^X//" >'./rrnpatches/Configure.pat' <<'END_OF_FILE'
- X*** rn/Configure Sun Mar 15 19:54:19 1987
- X--- rrn/Configure Thu Feb 25 20:56:09 1988
- X***************
- X*** 77,82
- X Log=''
- X Header=''
- X sitename=''
- X orgname=''
- X isadmin=''
- X newsadmin=''
- X
- X--- 77,83 -----
- X Log=''
- X Header=''
- X sitename=''
- X+ domain=''
- X orgname=''
- X isadmin=''
- X newsadmin=''
- X***************
- X*** 117,122
- X phostname=''
- X hostcmd=''
- X norelay=''
- X CONFIG=''
- X
- X echo "Beginning of configuration questions for rn kit."
- X
- X--- 118,127 -----
- X phostname=''
- X hostcmd=''
- X norelay=''
- X+ isrrn=''
- X+ rrnserver=''
- X+ serverfile=''
- X+ NNTPSRC=''
- X CONFIG=''
- X
- X echo "Beginning of configuration questions for rn kit."
- X***************
- X*** 681,686
- X hostcmd=''
- X done
- X
- X : get organizaton name
- X longshots='/usr/src/new /usr/src/local /usr/local/src'
- X case "$orgname" in
- X
- X--- 686,725 -----
- X hostcmd=''
- X done
- X
- X+ : try to deal with domains
- X+ $cat << 'EOH'
- X+
- X+ Please enter your domain name. This will be used in conjunction
- X+ with the site name for return addresses on news articles and
- X+ mail. If you use the 4.3ism of having your domain in your
- X+ hostname, all the posting programs will figure this out on the
- X+ fly, so don't worry.
- X+
- X+ Examples of some valid domains:
- X+
- X+ uucp
- X+ arpa
- X+ berkeley.edu
- X+ nsa.gov
- X+
- X+ EOH
- X+
- X+ dflt="uucp"
- X+ $echo $n "Your domain: [$dflt] $c"
- X+ . myread
- X+ case "$ans" in
- X+ '') domain="$dflt";;
- X+ *) domain="$ans" ;;
- X+ esac
- X+
- X+ if $test $portable = "undef" ; then
- X+ case $sitename in
- X+ *.*) ;;
- X+ *) sitename=$sitename.$domain
- X+ ;;
- X+ esac
- X+ fi
- X+
- X : get organizaton name
- X longshots='/usr/src/new /usr/src/local /usr/local/src'
- X case "$orgname" in
- X***************
- X*** 769,774
- X blurfl*) ;;
- X *) $echo "Directory $libexp not found";;
- X esac
- X echo $n "Where is your news library (~name okay)? [$dflt] $c"
- X . myread
- X case "$ans" in
- X
- X--- 808,817 -----
- X blurfl*) ;;
- X *) $echo "Directory $libexp not found";;
- X esac
- X+ echo "(If you are building this as rrn, it is a good idea"
- X+ echo "to make your news library directory the same as where the rn"
- X+ echo "library directory is, usually /usr/local/lib/rn)"
- X+ echo " "
- X echo $n "Where is your news library (~name okay)? [$dflt] $c"
- X . myread
- X case "$ans" in
- X***************
- X*** 1281,1287
- X fi
- X fi
- X
- X! : locate spool directory
- X case "$spool" in
- X '')
- X dflt=/usr/spool/news
- X
- X--- 1324,1422 -----
- X fi
- X fi
- X
- X! : locate spool directory and check if rrn
- X! case "$isrrn" in
- X! define)
- X! dflt="y";;
- X! *)
- X! dflt="n";;
- X! esac
- X! isrrn=''
- X! while $test -z "$isrrn" ; do
- X! $echo " "
- X! $echo $n "Do you want this built as remote rn (rrn)? [$dflt] $c"
- X! . myread
- X! case "$ans" in
- X! '') ans="$dflt";;
- X! esac
- X! case "$ans" in
- X! n*)
- X! isrrn=undef;;
- X! y*)
- X! isrrn=define
- X! spool=/tmp
- X! $echo "net.foobar 00001 00001 y" > .falseactive
- X!
- X! case "$serverfile" in
- X! '') dflt="no default" ;;
- X! *) dflt="$serverfile";;
- X! esac
- X!
- X! $cat <<'EOM'
- X!
- X! rrn determines the machine to use as a news server by two means:
- X!
- X! 1. It examines the environment variable NNTPSERVER for
- X! a machine name; this allows users to use server machines
- X! other than the default.
- X!
- X! 2. It looks in a file which contains the name of a server
- X! machine.
- X!
- X! You must create the file mentioned in (2), above. Simply put the name
- X! of the machine you wish to use as your news server in this file.
- X! If you really want, you can use # for comments and blank lines in
- X! this file as well.
- X!
- X! EOM
- X!
- X! ans=''
- X! while $test -z "$ans" ; do
- X! $echo $n "Enter the name of the news server file: [$dflt] $c"
- X! . myread
- X! done
- X! serverfile="$ans"
- X!
- X! case "$rrnserver" in
- X! '') dflt="no default" ;;
- X! *) dflt="$rrnserver";;
- X! esac
- X!
- X! case "$NNTPSRC" in
- X! '') dflt="no default";;
- X! *) dflt="$NNTPSRC";;
- X! esac
- X!
- X! ans='blurfl/dyick'
- X! while $test ! -d "$ans"; do
- X! $echo $n "Enter the pathname of the NNTP source directory: [$dflt] $c"
- X! . myread
- X! case "$ans" in
- X! '') ans="$dflt";;
- X! esac
- X! ans=`filexp "$ans"`
- X! if $test ! -r $ans/common/nntp.h ; then
- X! ans='blurfl/dyick'
- X! fi
- X! done
- X! NNTPSRC="$ans"
- X! cat > server.h <<EOF_SERVE
- X! #ifdef SERVER
- X!
- X! EXT char *getserverbyfile();
- X! EXT int server_init();
- X! EXT void put_server();
- X! EXT int get_server();
- X! EXT void close_server();
- X!
- X! #include "$NNTPSRC/common/nntp.h"
- X! #endif
- X! EOF_SERVE
- X!
- X! esac
- X!
- X! done
- X!
- X case "$spool" in
- X '')
- X dflt=/usr/spool/news
- X***************
- X*** 1288,1294
- X ;;
- X *) dflt="$spool";;
- X esac
- X! ans='blurfl/dyick'
- X while $test ! -d $ans; do
- X $echo " "
- X case "$ans" in
- X
- X--- 1423,1432 -----
- X ;;
- X *) dflt="$spool";;
- X esac
- X! case "$isrrn" in
- X! define) ans=/tmp;;
- X! *) ans='blurfl/dyick';;
- X! esac
- X while $test ! -d $ans; do
- X $echo " "
- X case "$ans" in
- X***************
- X*** 1322,1328
- X ;;
- X *) dflt="$active";;
- X esac
- X! myactive='blurfl/dyick'
- X while $test ! -f "$myactive"; do
- X $echo " "
- X case "$myactive" in
- X
- X--- 1460,1469 -----
- X ;;
- X *) dflt="$active";;
- X esac
- X! case "$isrrn" in
- X! define) myactive=.falseactive;;
- X! *) myactive='blurfl/dyick'
- X! esac
- X while $test ! -f "$myactive"; do
- X $echo " "
- X case "$myactive" in
- X***************
- X*** 1799,1804
- X Log='$Log'
- X Header='$Header'
- X sitename='$sitename'
- X orgname='$orgname'
- X isadmin='$isadmin'
- X newsadmin='$newsadmin'
- X
- X--- 1940,1946 -----
- X Log='$Log'
- X Header='$Header'
- X sitename='$sitename'
- X+ domain='$domain'
- X orgname='$orgname'
- X isadmin='$isadmin'
- X newsadmin='$newsadmin'
- X***************
- X*** 1839,1844
- X phostname='$phostname'
- X hostcmd='$hostcmd'
- X norelay='$norelay'
- X CONFIG=true
- X EOT
- X
- X
- X--- 1981,1989 -----
- X phostname='$phostname'
- X hostcmd='$hostcmd'
- X norelay='$norelay'
- X+ isrrn='$isrrn'
- X+ rrnserver='$rrnserver'
- X+ NNTPSRC='$NNTPSRC'
- X CONFIG=true
- X EOT
- X
- X***************
- X*** 1926,1931
- X #$douname DOUNAME /* do we have a uname function? */
- X #$phostname PHOSTNAME "$hostcmd" /* how to get host name with popen */
- X #$norelay NORELAY /* 2.10.3 doesn't have Relay-Version line */
- X EOT
- X
- X CONFIG=true
- X
- X--- 2071,2079 -----
- X #$douname DOUNAME /* do we have a uname function? */
- X #$phostname PHOSTNAME "$hostcmd" /* how to get host name with popen */
- X #$norelay NORELAY /* 2.10.3 doesn't have Relay-Version line */
- X+ #$isrrn SERVER /* rrn server code */
- X+ #$isrrn SERVER_HOST "$rrnserver"
- X+ #$isrrn SERVER_FILE "$serverfile"
- X EOT
- X
- X CONFIG=true
- END_OF_FILE
- if test 6499 -ne `wc -c <'./rrnpatches/Configure.pat'`; then
- echo shar: \"'./rrnpatches/Configure.pat'\" unpacked with wrong size!
- fi
- # end of './rrnpatches/Configure.pat'
- fi
- if test -f './rrnpatches/rcstuff.c.pat' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rrnpatches/rcstuff.c.pat'\"
- else
- echo shar: Extracting \"'./rrnpatches/rcstuff.c.pat'\" \(6131 characters\)
- sed "s/^X//" >'./rrnpatches/rcstuff.c.pat' <<'END_OF_FILE'
- X*** rn/rcstuff.c Sun Mar 15 19:54:20 1987
- X--- rrn/rcstuff.c Fri May 29 09:33:43 1987
- X***************
- X*** 31,36
- X #include "intrp.h"
- X #include "only.h"
- X #include "rcln.h"
- X #include "INTERN.h"
- X #include "rcstuff.h"
- X
- X
- X--- 31,37 -----
- X #include "intrp.h"
- X #include "only.h"
- X #include "rcln.h"
- X+ #include "server.h"
- X #include "INTERN.h"
- X #include "rcstuff.h"
- X
- X***************
- X*** 53,58
- X register bool foundany = FALSE;
- X char *some_buf;
- X long length;
- X
- X #ifdef HASHNG
- X for (i=0; i<HASHSIZ; i++)
- X
- X--- 54,62 -----
- X register bool foundany = FALSE;
- X char *some_buf;
- X long length;
- X+ #ifdef SERVER
- X+ char *cp;
- X+ #endif SERVER
- X
- X #ifdef HASHNG
- X for (i=0; i<HASHSIZ; i++)
- X***************
- X*** 61,66
- X
- X /* make filenames */
- X
- X rcname = savestr(filexp(RCNAME));
- X rctname = savestr(filexp(RCTNAME));
- X rcbname = savestr(filexp(RCBNAME));
- X
- X--- 65,79 -----
- X
- X /* make filenames */
- X
- X+ #ifdef SERVER
- X+
- X+ if (cp = getenv("NEWSRC"))
- X+ rcname = savestr(filexp(cp));
- X+ else
- X+ rcname = savestr(filexp(RCNAME));
- X+
- X+ #else not SERVER
- X+
- X rcname = savestr(filexp(RCNAME));
- X
- X #endif SERVER
- X***************
- X*** 62,67
- X /* make filenames */
- X
- X rcname = savestr(filexp(RCNAME));
- X rctname = savestr(filexp(RCTNAME));
- X rcbname = savestr(filexp(RCBNAME));
- X softname = savestr(filexp(SOFTNAME));
- X
- X--- 75,83 -----
- X #else not SERVER
- X
- X rcname = savestr(filexp(RCNAME));
- X+
- X+ #endif SERVER
- X+
- X rctname = savestr(filexp(RCTNAME));
- X rcbname = savestr(filexp(RCBNAME));
- X softname = savestr(filexp(SOFTNAME));
- X***************
- X*** 224,229
- X /* returns TRUE if found or added, FALSE if not. */
- X /* assumes that we are chdir'ed to SPOOL */
- X
- X bool
- X get_ng(what,do_reloc)
- X char *what;
- X
- X--- 240,249 -----
- X /* returns TRUE if found or added, FALSE if not. */
- X /* assumes that we are chdir'ed to SPOOL */
- X
- X+ #ifdef SERVER
- X+ static int addnewbydefault = 0;
- X+ #endif SERVER
- X+
- X bool
- X get_ng(what,do_reloc)
- X char *what;
- X***************
- X*** 231,236
- X {
- X char *ntoforget;
- X char promptbuf[128];
- X
- X #ifdef VERBOSE
- X IF(verbose)
- X
- X--- 251,259 -----
- X {
- X char *ntoforget;
- X char promptbuf[128];
- X+ #ifdef SERVER
- X+ char ser_line[256];
- X+ #endif SERVER
- X
- X #ifdef VERBOSE
- X IF(verbose)
- X***************
- X*** 248,253
- X set_ngname(what);
- X ng = find_ng(ngname);
- X if (ng == nextrcline) { /* not in .newsrc? */
- X if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
- X dingaling();
- X #ifdef VERBOSE
- X
- X--- 271,291 -----
- X set_ngname(what);
- X ng = find_ng(ngname);
- X if (ng == nextrcline) { /* not in .newsrc? */
- X+
- X+ #ifdef SERVER
- X+ sprintf(ser_line, "GROUP %s", ngname);
- X+ put_server(ser_line);
- X+ if (get_server(ser_line, sizeof(ser_line)) < 0) {
- X+ fprintf(stderr, "rrn: Unexpected close of server socket.\n");
- X+ finalize(1);
- X+ }
- X+ if (*ser_line != CHAR_OK) {
- X+ if (atoi(ser_line) != ERR_NOGROUP) {
- X+ fprintf(stderr, "Server response to GROUP %s:\n%s\n",
- X+ ngname, ser_line);
- X+ }
- X+ #else not SERVER
- X+
- X if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
- X
- X #endif SERVER
- X***************
- X*** 249,254
- X ng = find_ng(ngname);
- X if (ng == nextrcline) { /* not in .newsrc? */
- X if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
- X dingaling();
- X #ifdef VERBOSE
- X IF(verbose)
- X
- X--- 287,295 -----
- X #else not SERVER
- X
- X if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
- X+
- X+ #endif SERVER
- X+
- X dingaling();
- X #ifdef VERBOSE
- X IF(verbose)
- X***************
- X*** 261,266
- X sleep(2);
- X return FALSE;
- X }
- X #ifdef VERBOSE
- X IF(verbose)
- X sprintf(promptbuf,"\nNewsgroup %s not in .newsrc--add? [yn] ",ngname);
- X
- X--- 302,314 -----
- X sleep(2);
- X return FALSE;
- X }
- X+ #ifdef SERVER
- X+ if (addnewbydefault) {
- X+ printf("(Adding %s to end of your .newsrc)\n", ngname);
- X+ ng = add_newsgroup(ngname);
- X+ do_reloc = FALSE;
- X+ } else {
- X+ #endif SERVER
- X #ifdef VERBOSE
- X IF(verbose)
- X sprintf(promptbuf,"\nNewsgroup %s not in .newsrc--add? [yn] ",ngname);
- X***************
- X*** 296,301
- X ng = add_newsgroup(ngname);
- X do_reloc = FALSE;
- X }
- X else {
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X
- X--- 344,359 -----
- X ng = add_newsgroup(ngname);
- X do_reloc = FALSE;
- X }
- X+ #ifdef SERVER
- X+ else if (*buf == 'Y') {
- X+ fputs(
- X+ "(I'll add all new newsgroups to the end of your .newsrc.)\n", stdout);
- X+ addnewbydefault = 1;
- X+ printf("(Adding %s to end of your .newsrc)\n", ngname);
- X+ ng = add_newsgroup(ngname);
- X+ do_reloc = FALSE;
- X+ }
- X+ #endif SERVER
- X else {
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X***************
- X*** 301,306
- X settle_down();
- X goto reask_add;
- X }
- X }
- X else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */
- X #ifdef VERBOSE
- X
- X--- 359,367 -----
- X settle_down();
- X goto reask_add;
- X }
- X+ #ifdef SERVER
- X+ }
- X+ #endif SERVER
- X }
- X else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */
- X #ifdef VERBOSE
- X***************
- X*** 453,458
- X if (newng < 0) {
- X reask_reloc:
- X unflush_output(); /* disable any ^O in effect */
- X #ifdef VERBOSE
- X IF(verbose)
- X printf("\nPut newsgroup where? [%s] ", dflt);
- X
- X--- 514,525 -----
- X if (newng < 0) {
- X reask_reloc:
- X unflush_output(); /* disable any ^O in effect */
- X+ #ifdef SERVER
- X+ if (addnewbydefault) {
- X+ buf[0] = '$';
- X+ buf[1] = '\0';
- X+ } else {
- X+ #endif SERVER
- X #ifdef VERBOSE
- X IF(verbose)
- X printf("\nPut newsgroup where? [%s] ", dflt);
- X***************
- X*** 465,470
- X reinp_reloc:
- X eat_typeahead();
- X getcmd(buf);
- X if (errno || *buf == '\f') {
- X /* if return from stop signal */
- X goto reask_reloc; /* give them a prompt again */
- X
- X--- 532,540 -----
- X reinp_reloc:
- X eat_typeahead();
- X getcmd(buf);
- X+ #ifdef SERVER
- X+ }
- X+ #endif SERVER
- X if (errno || *buf == '\f') {
- X /* if return from stop signal */
- X goto reask_reloc; /* give them a prompt again */
- END_OF_FILE
- if test 6131 -ne `wc -c <'./rrnpatches/rcstuff.c.pat'`; then
- echo shar: \"'./rrnpatches/rcstuff.c.pat'\" unpacked with wrong size!
- fi
- # end of './rrnpatches/rcstuff.c.pat'
- fi
- if test -f './server/serve.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./server/serve.c'\"
- else
- echo shar: Extracting \"'./server/serve.c'\" \(6497 characters\)
- sed "s/^X//" >'./server/serve.c' <<'END_OF_FILE'
- X#ifndef lint
- static char *sccsid = "@(#)serve.c 1.29 (Berkeley) 2/6/88";
- X#endif
- X
- X/*
- X * Main server routine
- X */
- X
- X#include "common.h"
- X#include <signal.h>
- X#ifdef USG
- X#include <sys/times.h>
- X#else
- X#include <sys/time.h>
- X#endif
- X
- X#ifdef LOG
- X# ifndef USG
- X# include <sys/resource.h>
- X# endif not USG
- X#endif
- X
- extern int ahbs(), group(), help(), ihave();
- extern int list(), newgroups(), newnews(), nextlast(), post();
- extern int slave(), stat(), xhdr();
- X
- static struct cmdent {
- X char *cmd_name;
- X int (*cmd_fctn)();
- X} cmdtbl[] = {
- X "article", ahbs,
- X "body", ahbs,
- X "group", group,
- X "head", ahbs,
- X "help", help,
- X "ihave", ihave,
- X "last", nextlast,
- X "list", list,
- X "newgroups", newgroups,
- X "newnews", newnews,
- X "next", nextlast,
- X "post", post,
- X "slave", slave,
- X "stat", ahbs,
- X#ifdef XHDR
- X "xhdr", xhdr,
- X#endif XHDR
- X};
- X#define NUMCMDS (sizeof(cmdtbl) / sizeof(struct cmdent))
- X
- X
- X/*
- X * serve -- given a connection on stdin/stdout, serve
- X * a client, executing commands until the client
- X * says goodbye.
- X *
- X * Parameters: None.
- X *
- X * Returns: Exits.
- X *
- X * Side effects: Talks to client, does a lot of
- X * stuff.
- X */
- X
- serve()
- X{
- X char line[NNTP_STRLEN];
- X char host[MAXHOSTNAMELEN];
- X char gdbuf[MAXBUFLEN];
- X char **argp;
- X char *timeptr, *cp;
- X int argnum, i;
- X double Tstart, Tfinish;
- X double user, sys;
- X#ifdef USG
- X time_t start, finish;
- X#else not USG
- X struct timeval start, finish;
- X#endif not USG
- X extern char *ctime();
- X#ifdef POSTER
- X struct passwd *pp;
- X#endif
- X#ifdef LOG
- X# ifdef USG
- X struct tms cpu;
- X# else not USG
- X struct rusage me, kids;
- X# endif not USG
- X# ifdef TIMEOUT
- X void timeout();
- X# endif
- X
- X grps_acsd = arts_acsd = 0;
- X#endif
- X
- X /* Not all systems pass fd's 1 and 2 from inetd */
- X
- X (void) close(1);
- X (void) close(2);
- X (void) dup(0);
- X (void) dup(0);
- X
- X /* If we're ALONE, then we've already opened syslog */
- X
- X#ifndef ALONE
- X# ifdef SYSLOG
- X# ifdef BSD_42
- X openlog("nntpd", LOG_PID);
- X# else
- X openlog("nntpd", LOG_PID, SYSLOG);
- X# endif
- X# endif
- X#endif
- X
- X#ifdef ALONE
- X#ifndef USG
- X (void) signal(SIGCHLD, SIG_IGN);
- X#endif not USG
- X#endif
- X
- X /* Ignore SIGPIPE, since we'll see closed connections with read */
- X
- X (void) signal(SIGPIPE, SIG_IGN);
- X
- X /* Get permissions and see if we can talk to this client */
- X
- X host_access(&canread, &canpost, &canxfer, gdbuf);
- X
- X if (gethostname(host, sizeof(host)) < 0)
- X (void) strcpy(host, "Amnesiac");
- X
- X if (!canread && !canxfer) {
- X printf("%d %s NNTP server can't talk to you. Goodbye.\r\n",
- X ERR_ACCESS, host);
- X (void) fflush(stdout);
- X#ifdef LOG
- X syslog(LOG_INFO, "%s refused connection", hostname);
- X#endif
- X exit(1);
- X }
- X
- X /* If we can talk, proceed with initialization */
- X
- X ngpermcount = get_nglist(&ngpermlist, gdbuf);
- X
- X#ifdef POSTER
- X pp = getpwnam(POSTER);
- X if (pp != NULL) {
- X uid_poster = pp->pw_uid;
- X gid_poster = pp->pw_gid;
- X } else
- X#endif
- X uid_poster = gid_poster = 0;
- X
- X#ifndef FASTFORK
- X num_groups = 0;
- X num_groups = read_groups(); /* Read in the active file */
- X#else
- X signal(SIGALRM, SIG_IGN); /* Children don't deal with */
- X /* these things */
- X#endif
- X
- X art_fp = NULL;
- X argp = (char **) NULL; /* for first time */
- X
- X#ifdef USG
- X (void) time(&start);
- X Tstart = (double) start;
- X timeptr = ctime(&start);
- X#else not USG
- X (void) gettimeofday(&start, (struct timezone *)NULL);
- X Tstart = (double) start.tv_sec - ((double)start.tv_usec)/1000000.0;
- X timeptr = ctime(&start.tv_sec);
- X#endif not USG
- X if ((cp = index(timeptr, '\n')) != NULL)
- X *cp = '\0';
- X else
- X timeptr = "Unknown date";
- X
- X printf("%d %s NNTP server version %s ready at %s (%s).\r\n",
- X canpost ? OK_CANPOST : OK_NOPOST,
- X host, nntp_version,
- X timeptr,
- X canpost ? "posting ok" : "no posting");
- X (void) fflush(stdout);
- X
- X /*
- X * Now get commands one at a time and execute the
- X * appropriate routine to deal with them.
- X */
- X
- X#ifdef TIMEOUT
- X (void) signal(SIGALRM, timeout);
- X (void) alarm(TIMEOUT);
- X#endif TIMEOUT
- X
- X while (fgets(line, sizeof(line), stdin) != NULL) {
- X#ifdef TIMEOUT
- X (void) alarm(0);
- X#endif TIMEOUT
- X
- X cp = index(line, '\r'); /* Zap CR-LF */
- X if (cp != NULL)
- X *cp = '\0';
- X else {
- X cp = index(line, '\n');
- X if (cp != NULL)
- X *cp = '\0';
- X }
- X
- X if ((argnum = parsit(line, &argp)) == 0)
- X continue; /* Null command */
- X else {
- X for (i = 0; i < NUMCMDS; ++i)
- X if (!strcasecmp(cmdtbl[i].cmd_name, argp[0]))
- X break;
- X if (i < NUMCMDS)
- X (*cmdtbl[i].cmd_fctn)(argnum, argp);
- X else {
- X if (!strcasecmp(argp[0], "quit"))
- X break;
- X#ifdef LOG
- X syslog(LOG_INFO, "%s unrecognized %s",
- X hostname,
- X line);
- X#endif
- X printf("%d Command unrecognized.\r\n",
- X ERR_COMMAND);
- X (void) fflush(stdout);
- X }
- X }
- X#ifdef TIMEOUT
- X (void) alarm(TIMEOUT);
- X#endif TIMEOUT
- X }
- X
- X printf("%d %s closing connection. Goodbye.\r\n", OK_GOODBYE, host);
- X (void) fflush(stdout);
- X
- X
- X#ifdef LOG
- X if (ferror(stdout))
- X syslog(LOG_ERR, "%s disconnect: %m", hostname);
- X
- X#ifdef USG
- X (void) time(&finish);
- X Tfinish = (double) finish;
- X
- X#ifndef HZ
- X#define HZ 60.0 /* typical system clock ticks - param.h */
- X#endif not HZ
- X
- X (void) times(&cpu);
- X user = (double)(cpu.tms_utime + cpu.tms_cutime) / HZ;
- X sys = (double)(cpu.tms_stime + cpu.tms_cstime) / HZ;
- X#else not USG
- X (void) gettimeofday(&finish, (struct timezone *)NULL);
- X Tfinish = (double) finish.tv_sec - ((double)finish.tv_usec)/1000000.0;
- X
- X (void) getrusage(RUSAGE_SELF, &me);
- X (void) getrusage(RUSAGE_CHILDREN, &kids);
- X
- X user = (double) me.ru_utime.tv_sec + me.ru_utime.tv_usec/1000000.0 +
- X kids.ru_utime.tv_sec + kids.ru_utime.tv_usec/1000000.0;
- X sys = (double) me.ru_stime.tv_sec + me.ru_stime.tv_usec/1000000.0 +
- X kids.ru_stime.tv_sec + kids.ru_stime.tv_usec/1000000.0;
- X#endif not USG
- X if (grps_acsd)
- X syslog(LOG_INFO, "%s exit %d articles %d groups",
- X hostname, arts_acsd, grps_acsd);
- X if (nn_told)
- X syslog(LOG_INFO, "%s newnews_stats told %d took %d",
- X hostname, nn_told, nn_took);
- X if (ih_accepted || ih_rejected || ih_failed)
- X syslog(LOG_INFO,
- X "%s ihave_stats accepted %d rejected %d failed %d",
- X hostname,
- X ih_accepted,
- X ih_rejected,
- X ih_failed);
- X (void) sprintf(line, "user %.1f system %.1f elapsed %.1f",
- X user, sys, Tfinish - Tstart);
- X syslog(LOG_INFO, "%s times %s", hostname, line);
- X#endif LOG
- X
- X#ifdef PROFILE
- X profile();
- X#endif
- X
- X exit(0);
- X}
- X
- X
- X#ifdef TIMEOUT
- X/*
- X * No activity for TIMEOUT seconds, so print an error message
- X * and close the connection.
- X */
- X
- void
- timeout()
- X{
- X printf("%d Timeout after %d seconds, closing connection.\r\n",
- X ERR_FAULT, TIMEOUT);
- X (void) fflush(stdout);
- X
- X#ifdef LOG
- X syslog(LOG_ERR, "%s timeout", hostname);
- X#endif LOG
- X
- X exit(1);
- X}
- X#endif TIMEOUT
- END_OF_FILE
- if test 6497 -ne `wc -c <'./server/serve.c'`; then
- echo shar: \"'./server/serve.c'\" unpacked with wrong size!
- fi
- # end of './server/serve.c'
- fi
- if test -f './server/subnet.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./server/subnet.c'\"
- else
- echo shar: Extracting \"'./server/subnet.c'\" \(6358 characters\)
- sed "s/^X//" >'./server/subnet.c' <<'END_OF_FILE'
- X#ifndef lint
- static char *sccsid = "@(#)subnet.c 1.5 (Berkeley) 1/4/88";
- X#endif
- X
- X#include "../common/conf.h"
- X
- X#ifdef SUBNET
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#ifndef NETMASK
- X#include <net/if.h>
- X#endif
- X#include <sys/ioctl.h>
- X
- X/*
- X * The following routines provide a general interface for
- X * subnet support. Like the library function "inet_netof",
- X * which returns the standard (i.e., non-subnet) network
- X * portion of an internet address, "inet_snetof" returns
- X * the subnetwork portion -- if there is one. If there
- X * isn't, it returns 0.
- X *
- X * Subnets, under 4.3, are specific to a given set of
- X * machines -- right down to the network interfaces.
- X * Because of this, the function "getifconf" must be
- X * called first. This routine builds a table listing
- X * all the (internet) interfaces present on a machine,
- X * along with their subnet masks. Then when inet_snetof
- X * is called, it can quickly scan this table.
- X *
- X * Unfortunately, there "ain't no graceful way" to handle
- X * certain situations. For example, the kernel permits
- X * arbitrary subnet bits -- that is, you could have a
- X * 22 bit network field and a 10 bit subnet field.
- X * However, due to braindamage at the user level, in
- X * such sterling routines as getnetbyaddr, you need to
- X * have a subnet mask which is an even multiple of 8.
- X * Unless you are running with class C subnets, in which
- X * case it should be a multiple of 4. Because of this rot,
- X * if you have non-multiples of 4 bits of subnet, you should
- X * define DAMAGED_NETMASK when you compile. This will round
- X * things off to a multiple of 8 bits.
- X *
- X * Finally, you may want subnet support even if your system doesn't
- X * support the ioctls to get subnet mask information. If you want
- X * such a thing, you can define NETMASK to be a constant that is
- X * the subnet mask for your network.
- X *
- X * And don't *even* get me started on how the definitions of the inet_foo()
- X * routines changed between 4.2 and 4.3, making internet addresses
- X * be unsigned long vs. struct in_addr. Don't blame me if this
- X * won't lint...
- X */
- X
- X/*
- X * One structure for each interface, containing
- X * the network number and subnet mask, stored in HBO.
- X */
- struct in_if {
- X u_long i_net; /* Network number, shifted right */
- X u_long i_subnetmask; /* Subnet mask for this if */
- X int i_bitshift; /* How many bits right for outside */
- X};
- X
- X/*
- X * Table (eventually, once we malloc) of
- X * internet interface subnet informaiton.
- X */
- static struct in_if *in_ifsni;
- X
- static int if_count;
- X
- X/*
- X * Get the network interface configuration,
- X * and squirrel away the network numbers and
- X * subnet masks of each interface. Return
- X * number of interfaces found, or -1 on error.
- X * N.B.: don't call this more than once...
- X */
- X
- getifconf()
- X{
- X#ifndef NETMASK
- X register int i, j;
- X int s;
- X struct ifconf ifc;
- X char buf[1024];
- X register struct ifreq *ifr;
- X u_long inet_netof();
- X u_long addr;
- X
- X /*
- X * Find out how many interfaces we have, and malloc
- X * room for information about each one.
- X */
- X
- X s = socket(AF_INET, SOCK_DGRAM, 0);
- X if (s < 0)
- X return (-1);
- X
- X ifc.ifc_buf = buf;
- X ifc.ifc_len = sizeof (buf);
- X
- X if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
- X (void) close(s);
- X return (-1);
- X }
- X
- X /*
- X * if_count here is the count of possible
- X * interfaces we may be interested in... actual
- X * interfaces may be less (some may not be internet,
- X * not all are necessarily up, etc.)
- X */
- X
- X if_count = ifc.ifc_len / sizeof (struct ifreq);
- X
- X in_ifsni = (struct in_if *) malloc(if_count * sizeof (struct in_if));
- X if (in_ifsni == 0) {
- X (void) close(s);
- X return (-1);
- X }
- X
- X for (i = j = 0; i < if_count; ++i) {
- X ifr = &ifc.ifc_req[i];
- X if (ioctl(s, SIOCGIFFLAGS, ifr) < 0)
- X continue;
- X if ((ifr->ifr_flags & IFF_UP) == 0)
- X continue;
- X if (ioctl(s, SIOCGIFADDR, ifr) < 0)
- X continue;
- X if (ifr->ifr_addr.sa_family != AF_INET)
- X continue;
- X addr = (*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr;
- X in_ifsni[j].i_net = inet_netof(addr);
- X if (ioctl(s, SIOCGIFNETMASK, ifr) < 0)
- X continue;
- X in_ifsni[j].i_subnetmask =
- X ntohl((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr);
- X /*
- X * The following should "never happen". But under SunOs
- X * 3.4, along with the rest of their broken networking code,
- X * SIOCGIFNETMASK can get a netmask which is 0. There
- X * really isn't anything that "right" that we can do
- X * about it, so we'll set their subnet mask to be their
- X * *net*work mask. Which may or may not be right.
- X */
- X if (in_ifsni[j].i_subnetmask == 0) {
- X addr = ntohl(addr);
- X if (IN_CLASSA(addr))
- X in_ifsni[j].i_subnetmask = IN_CLASSA_NET;
- X else if (IN_CLASSB(addr))
- X in_ifsni[j].i_subnetmask = IN_CLASSB_NET;
- X else if (IN_CLASSC(addr))
- X in_ifsni[j].i_subnetmask = IN_CLASSC_NET;
- X else /* what to do ... */
- X in_ifsni[j].i_subnetmask = IN_CLASSC_NET;
- X } else
- X in_ifsni[j].i_bitshift = bsr(in_ifsni[j].i_subnetmask);
- X j++;
- X }
- X
- X if_count = j;
- X
- X (void) close(s);
- X
- X return (if_count);
- X
- X#else /* hard-coded subnets */
- X
- X if_count = 1;
- X
- X in_ifsni = (struct in_if *) malloc(if_count * sizeof (struct in_if));
- X if (in_ifsni == 0) {
- X return (-1);
- X }
- X in_ifsni[0].i_net = 0;
- X in_ifsni[0].i_subnetmask = NETMASK;
- X in_ifsni[0].i_bitshift = bsr(in_ifsni[0].i_subnetmask);
- X return (if_count);
- X#endif
- X}
- X
- X
- X/*
- X * Return the (sub)network number from an internet address.
- X * "in" is in NBO, return value in host byte order.
- X * If "in" is not a subnet, return 0.
- X */
- X
- u_long
- inet_snetof(in)
- X u_long in;
- X{
- X register int j;
- X register u_long i = ntohl(in);
- X register u_long net;
- X u_long inet_netof(), inet_lnaof();
- X
- X net = inet_netof(in);
- X
- X /*
- X * Check whether network is a subnet;
- X * if so, return subnet number.
- X */
- X for (j = 0; j < if_count; ++j)
- X#ifdef NETMASK
- X if (1) {
- X#else
- X if (net == in_ifsni[j].i_net) {
- X#endif
- X net = i & in_ifsni[j].i_subnetmask;
- X if (inet_lnaof(htonl(net)) == 0)
- X return (0);
- X else
- X return (net >> in_ifsni[j].i_bitshift);
- X }
- X
- X return (0);
- X}
- X
- X
- X/*
- X * Return the number of bits required to
- X * shift right a mask into a getnetent-able entitity.
- X */
- X
- bsr(mask)
- X register int mask;
- X{
- X register int count = 0;
- X
- X if (mask == 0) /* "never happen", except with SunOs 3.4 */
- X return (0);
- X
- X while ((mask & 1) == 0) {
- X ++count;
- X mask >>= 1;
- X }
- X#ifdef DAMAGED_NETMASK
- X count /= 8; /* XXX gag retch puke barf */
- X count *= 8;
- X#endif
- X return (count);
- X}
- X
- X#endif
- END_OF_FILE
- if test 6358 -ne `wc -c <'./server/subnet.c'`; then
- echo shar: \"'./server/subnet.c'\" unpacked with wrong size!
- fi
- # end of './server/subnet.c'
- fi
- if test -f './xmit/get_tcp_conn.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./xmit/get_tcp_conn.c'\"
- else
- echo shar: Extracting \"'./xmit/get_tcp_conn.c'\" \(7210 characters\)
- sed "s/^X//" >'./xmit/get_tcp_conn.c' <<'END_OF_FILE'
- X/*
- X** Routines to open a TCP connection
- X**
- X** New version that supports the old (pre 4.2 BSD) socket calls,
- X** and systems with the old (pre 4.2 BSD) hostname lookup stuff.
- X** Compile-time options are:
- X**
- X** USG - you're on System III/V (you have my sympathies)
- X** NONETDB - old hostname lookup with rhost()
- X** OLDSOCKET - different args for socket() and connect()
- X**
- X** Erik E. Fair <fair@ucbarpa.berkeley.edu>
- X**
- X*/
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <ctype.h>
- X#include <stdio.h>
- X#include "get_tcp_conn.h"
- X#ifndef NONETDB
- X#include <netdb.h>
- X#endif NONETDB
- X
- extern int errno;
- extern char *Pname;
- extern char *errmsg();
- X#ifndef htons
- extern u_short htons();
- X#endif htons
- X#ifndef NONETDB
- extern char *inet_ntoa();
- extern u_long inet_addr();
- X#else
- X/*
- X * inet_addr for EXCELAN (which does not have it!)
- X *
- X */
- u_long
- inet_addr(cp)
- register char *cp;
- X{
- X u_long val, base, n;
- X register char c;
- X u_long octet[4], *octetptr = octet;
- X#ifndef htonl
- X extern u_long htonl();
- X#endif htonl
- again:
- X /*
- X * Collect number up to ``.''.
- X * Values are specified as for C:
- X * 0x=hex, 0=octal, other=decimal.
- X */
- X val = 0; base = 10;
- X if (*cp == '0')
- X base = 8, cp++;
- X if (*cp == 'x' || *cp == 'X')
- X base = 16, cp++;
- X while (c = *cp) {
- X if (isdigit(c)) {
- X val = (val * base) + (c - '0');
- X cp++;
- X continue;
- X }
- X if (base == 16 && isxdigit(c)) {
- X val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
- X cp++;
- X continue;
- X }
- X break;
- X }
- X if (*cp == '.') {
- X /*
- X * Internet format:
- X * a.b.c.d
- X * a.b.c (with c treated as 16-bits)
- X * a.b (with b treated as 24 bits)
- X */
- X if (octetptr >= octet + 4)
- X return (-1);
- X *octetptr++ = val, cp++;
- X goto again;
- X }
- X /*
- X * Check for trailing characters.
- X */
- X if (*cp && !isspace(*cp))
- X return (-1);
- X *octetptr++ = val;
- X /*
- X * Concoct the address according to
- X * the number of octet specified.
- X */
- X n = octetptr - octet;
- X switch (n) {
- X
- X case 1: /* a -- 32 bits */
- X val = octet[0];
- X break;
- X
- X case 2: /* a.b -- 8.24 bits */
- X val = (octet[0] << 24) | (octet[1] & 0xffffff);
- X break;
- X
- X case 3: /* a.b.c -- 8.8.16 bits */
- X val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
- X (octet[2] & 0xffff);
- X break;
- X
- X case 4: /* a.b.c.d -- 8.8.8.8 bits */
- X val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
- X ((octet[2] & 0xff) << 8) | (octet[3] & 0xff);
- X break;
- X
- X default:
- X return (-1);
- X }
- X val = htonl(val);
- X return (val);
- X}
- X
- char *
- inet_ntoa(in)
- struct in_addr in;
- X{
- X static char address[20];
- X
- X sprintf(address, "%u.%u.%u.%u",
- X (in.s_addr>>24)&0xff,
- X (in.s_addr>>16)&0xff,
- X (in.s_addr>>8 )&0xff,
- X (in.s_addr )&0xff);
- X return(address);
- X}
- X#endif NONETDB
- X
- X#ifdef USG
- void
- bcopy(s, d, l)
- register caddr_t s, d;
- register int l;
- X{
- X while (l-- > 0) *d++ = *s++;
- X}
- X#endif USG
- X
- X/*
- X** Take the name of an internet host in ASCII (this may either be its
- X** official host name or internet number (with or without enclosing
- X** backets [])), and return a list of internet addresses.
- X**
- X** returns NULL for failure to find the host name in the local database,
- X** or for a bad internet address spec.
- X*/
- u_long **
- name_to_address(host)
- char *host;
- X{
- X static u_long *host_addresses[2];
- X static u_long haddr;
- X
- X if (host == (char *)NULL) {
- X return((u_long **)NULL);
- X }
- X
- X host_addresses[0] = &haddr;
- X host_addresses[1] = (u_long *)NULL;
- X
- X /*
- X ** Is this an ASCII internet address? (either of [10.0.0.78] or
- X ** 10.0.0.78). We get away with the second test because hostnames
- X ** and domain labels are not allowed to begin in numbers.
- X ** (cf. RFC952, RFC882).
- X */
- X if (*host == '[' || isdigit(*host)) {
- X char namebuf[128];
- X register char *cp = namebuf;
- X
- X /*
- X ** strip brackets [] or anything else we don't want.
- X */
- X while(*host != '\0' && cp < &namebuf[sizeof(namebuf)]) {
- X if (isdigit(*host) || *host == '.')
- X *cp++ = *host++; /* copy */
- X else
- X host++; /* skip */
- X }
- X *cp = '\0';
- X haddr = inet_addr(namebuf);
- X return(&host_addresses[0]);
- X } else {
- X#ifdef NONETDB
- X extern u_long rhost();
- X
- X /* lint is gonna bitch about this (comparing an unsigned?!) */
- X if ((haddr = rhost(&host)) == FAIL)
- X return((u_long **)NULL); /* no such host */
- X return(&host_addresses[0]);
- X#else
- X struct hostent *hstp = gethostbyname(host);
- X
- X if (hstp == NULL) {
- X return((u_long **)NULL); /* no such host */
- X }
- X
- X if (hstp->h_length != sizeof(u_long))
- X abort(); /* this is fundamental */
- X#ifndef h_addr
- X /* alignment problems (isn't dbm wonderful?) */
- X bcopy((caddr_t)hstp->h_addr, (caddr_t)&haddr, sizeof(haddr));
- X return(&host_addresses[0]);
- X#else
- X return((u_long **)hstp->h_addr_list);
- X#endif h_addr
- X#endif NONETDB
- X }
- X}
- X
- X/*
- X** Get a service port number from a service name (or ASCII number)
- X**
- X** Return zero if something is wrong (that's a reserved port)
- X*/
- X#ifdef NONETDB
- static struct Services {
- X char *name;
- X u_short port;
- X} Services[] = {
- X {"nntp", IPPORT_NNTP}, /* RFC977 */
- X {"smtp", IPPORT_SMTP}, /* RFC821 */
- X {"name", IPPORT_NAMESERVER}, /* RFC881, RFC882, RFC883 */
- X {"time", IPPORT_TIMESERVER}, /* RFC868 */
- X {"echo", IPPORT_ECHO}, /* RFC862 */
- X {"discard", IPPORT_DISCARD}, /* RFC863 */
- X {"daytime", IPPORT_DAYTIME}, /* RFC867 */
- X {"login", IPPORT_LOGINSERVER}, /* N/A - 4BSD specific */
- X};
- X#endif NONETDB
- X
- u_short
- gservice(serv, proto)
- char *serv, *proto;
- X{
- X if (serv == (char *)NULL || proto == (char *)NULL)
- X return((u_short)0);
- X
- X if (isdigit(*serv)) {
- X return(htons((u_short)(atoi(serv))));
- X } else {
- X#ifdef NONETDB
- X register int i;
- X
- X for(i = 0; i < (sizeof(Services) / sizeof(struct Services)); i++) {
- X if (strcmp(serv, Services[i].name) == 0)
- X return(htons(Services[i].port));
- X }
- X return((u_short)0);
- X#else
- X struct servent *srvp = getservbyname(serv, proto);
- X
- X if (srvp == (struct servent *)NULL)
- X return((u_short)0);
- X return((u_short)srvp->s_port);
- X#endif NONETDB
- X }
- X}
- X
- X/*
- X** given a host name (either name or internet address) and service name
- X** (or port number) (both in ASCII), give us a TCP connection to the
- X** requested service at the requested host (or give us FAIL).
- X*/
- get_tcp_conn(host, serv)
- char *host, *serv;
- X{
- X register int sock;
- X u_long **addrlist;
- X struct sockaddr_in sadr;
- X#ifdef OLDSOCKET
- X struct sockproto sp;
- X
- X sp.sp_family = (u_short)AF_INET;
- X sp.sp_protocol = (u_short)IPPROTO_TCP;
- X#endif OLDSOCKET
- X
- X if ((addrlist = name_to_address(host)) == (u_long **)NULL) {
- X return(NOHOST);
- X }
- X
- X sadr.sin_family = (u_short)AF_INET; /* Only internet for now */
- X if ((sadr.sin_port = gservice(serv, "tcp")) == 0)
- X return(NOSERVICE);
- X
- X for(; *addrlist != (u_long *)NULL; addrlist++) {
- X bcopy((caddr_t)*addrlist, (caddr_t)&sadr.sin_addr,
- X sizeof(sadr.sin_addr));
- X
- X#ifdef OLDSOCKET
- X if ((sock = socket(SOCK_STREAM, &sp, (struct sockaddr *)NULL, 0)) < 0)
- X return(FAIL);
- X
- X if (connect(sock, (struct sockaddr *)&sadr) < 0) {
- X#else
- X if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
- X return(FAIL);
- X
- X if (connect(sock, (struct sockaddr *)&sadr, sizeof(sadr)) < 0) {
- X#endif OLDSOCKET
- X int e_save = errno;
- X
- X fprintf(stderr, "%s: %s [%s]: %s\n", Pname, host,
- X inet_ntoa(sadr.sin_addr), errmsg(errno));
- X (void) close(sock); /* dump descriptor */
- X errno = e_save;
- X } else
- X return(sock);
- X }
- X return(FAIL);
- X}
- END_OF_FILE
- if test 7210 -ne `wc -c <'./xmit/get_tcp_conn.c'`; then
- echo shar: \"'./xmit/get_tcp_conn.c'\" unpacked with wrong size!
- fi
- # end of './xmit/get_tcp_conn.c'
- fi
- if test -f './xmit/shlock.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./xmit/shlock.c'\"
- else
- echo shar: Extracting \"'./xmit/shlock.c'\" \(6278 characters\)
- sed "s/^X//" >'./xmit/shlock.c' <<'END_OF_FILE'
- X/*
- X** Program to produce reliable locks for shell scripts.
- X** Algorithmn suggested by Peter Honeyman, January 1984,
- X** in connection with HoneyDanBer UUCP.
- X**
- X** I tried extending this to handle shared locks in November 1987,
- X** and ran into to some fundamental problems:
- X**
- X** Neither 4.3 BSD nor System V have an open(2) with locking,
- X** so that you can open a file and have it locked as soon as
- X** it's real; you have to make two system calls, and there's
- X** a race...
- X**
- X** When removing dead process id's from a list in a file,
- X** you need to truncate the file (you don't want to create a
- X** new one; see above); unfortunately for the portability of
- X** this program, only 4.3 BSD has ftruncate(2).
- X**
- X** Erik E. Fair <fair@ucbarpa.berkeley.edu>, November 8, 1987
- X*/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <fcntl.h> /* Needed on hpux */
- X#include <sys/file.h>
- X#include <errno.h>
- X
- X#define LOCK_SET 0
- X#define LOCK_FAIL 1
- X
- X#define FAIL (-1)
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- X#ifdef USG
- X#define index strchr
- X#define rindex strrchr
- X#endif
- X
- int Debug = FALSE;
- char *Pname;
- char *USAGE = "%s: USAGE: shlock -f file -p pid [-d]\n";
- char *errmsg();
- char *xtmpfile();
- X
- X#define dprintf if (Debug) printf
- X
- extern int errno;
- extern char *rindex();
- extern char *strcpy();
- extern char *strcat();
- X
- main(ac, av)
- int ac;
- char *av[];
- X{
- X register int x;
- X char *file;
- X int pid;
- X
- X Pname = ((Pname = rindex(av[0], '/')) ? Pname + 1 : av[0]);
- X
- X for(x = 1; x < ac; x++) {
- X if (av[x][0] == '-') {
- X switch(av[x][1]) {
- X case 'd':
- X Debug = TRUE;
- X break;
- X case 'p':
- X if (strlen(av[x]) > 2) {
- X pid = atoi(&av[x][2]);
- X } else {
- X pid = atoi(av[++x]);
- X }
- X break;
- X case 'f':
- X if (strlen(av[x]) > 2) {
- X file = &av[x][2];
- X } else {
- X file = av[++x];
- X }
- X break;
- X default:
- X fprintf(stderr, USAGE, Pname);
- X exit(LOCK_FAIL);
- X }
- X }
- X }
- X if (pid == 0 || file == (char *)NULL) {
- X fprintf(stderr, USAGE, Pname);
- X exit(LOCK_FAIL);
- X }
- X
- X exit(mklock(file, pid) ? LOCK_SET : LOCK_FAIL);
- X}
- X
- char *
- errmsg(n)
- register int n;
- X{
- X extern int sys_nerr;
- X extern char *sys_errlist[];
- X
- X return((n >= 0 && n < sys_nerr) ? sys_errlist[n] : "unknown error");
- X}
- X
- mklock(file, pid)
- char *file;
- int pid;
- X{
- X register char *tmp;
- X register int retcode = FALSE;
- X char *e_unlk = "%s: unlink(%s): %s\n";
- X
- X dprintf("%s: trying lock <%s> for process %d\n", Pname, file, pid);
- X if ((tmp = xtmpfile(file, pid)) == (char *)NULL)
- X return(FALSE);
- X
- linkloop:
- X if (link(tmp, file) < 0) {
- X switch(errno) {
- X case EEXIST:
- X dprintf("%s: lock <%s> already exists\n", Pname, file);
- X if (cklock(file)) {
- X dprintf("%s: extant lock is valid\n", Pname);
- X break;
- X } else {
- X dprintf("%s: lock is invalid, removing\n",
- X Pname);
- X if (unlink(file) < 0) {
- X fprintf(stderr, e_unlk,
- X Pname, file, errmsg(errno));
- X break;
- X }
- X }
- X /*
- X ** I hereby profane the god of structured programming,
- X ** Edsgar Dijkstra
- X */
- X goto linkloop;
- X default:
- X fprintf(stderr, "%s: link(%s, %s): %s\n",
- X Pname, tmp, file, errmsg(errno));
- X break;
- X }
- X } else {
- X dprintf("%s: got lock <%s>\n", Pname, file);
- X retcode = TRUE;
- X }
- X if (unlink(tmp) < 0) {
- X fprintf(stderr, e_unlk, Pname, tmp, errmsg(errno));
- X }
- X return(retcode);
- X}
- X
- X/*
- X** Does the PID exist?
- X** Send null signal to find out.
- X*/
- p_exists(pid)
- int pid;
- X{
- X dprintf("%s: process %d is ", Pname, pid);
- X if (pid <= 0) {
- X dprintf("invalid\n");
- X return(FALSE);
- X }
- X if (kill(pid, 0) < 0) {
- X switch(errno) {
- X case ESRCH:
- X dprintf("dead\n");
- X return(FALSE); /* pid does not exist */
- X case EPERM:
- X dprintf("alive\n");
- X return(TRUE); /* pid exists */
- X default:
- X dprintf("state unknown: %s\n", errmsg(errno));
- X return(TRUE); /* be conservative */
- X }
- X }
- X dprintf("alive\n");
- X return(TRUE); /* pid exists */
- X}
- X
- X/*
- X** Check the validity of an existing lock file.
- X**
- X** Read the PID out of the lock
- X** Send a null signal to determine whether that PID still exists
- X** Existence (or not) determines the validity of the lock.
- X**
- X** Two bigs wins to this algorithmn:
- X**
- X** o Locks do not survive crashes of either the system or the
- X** application by any appreciable period of time.
- X**
- X** o No clean up to do if the system or application crashes.
- X**
- X*/
- X
- cklock(file)
- char *file;
- X{
- X register int fd = open(file, O_RDONLY);
- X register int len;
- X char buf[BUFSIZ];
- X
- X dprintf("%s: checking extant lock <%s>\n", Pname, file);
- X if (fd < 0) {
- X fprintf(stderr,"%s: open(%s): %s\n", Pname, file, errmsg(errno));
- X return(TRUE); /* might or might not; conservatism */
- X }
- X
- X if ((len = read(fd, buf, sizeof(buf))) <= 0) {
- X close(fd);
- X dprintf("%s: lock file format error\n", Pname);
- X return(FALSE);
- X }
- X close(fd);
- X buf[len + 1] = '\0';
- X return(p_exists(atoi(buf)));
- X}
- X
- X/*
- X** Create a temporary file, all ready to lock with.
- X** The file arg is so we get the filename right, if he
- X** gave us a full path, instead of using the current directory
- X** which might not be in the same filesystem.
- X*/
- char *
- xtmpfile(file, pid)
- char *file;
- int pid;
- X{
- X register int fd;
- X register int len;
- X char *cp, buf[BUFSIZ];
- X static char tempname[BUFSIZ];
- X
- X sprintf(buf, "shlock%d", getpid());
- X if ((cp = rindex(strcpy(tempname, file), '/')) != (char *)NULL) {
- X *++cp = '\0';
- X (void) strcat(tempname, buf);
- X } else
- X (void) strcpy(tempname, buf);
- X dprintf("%s: temporary filename: %s\n", Pname, tempname);
- X
- X sprintf(buf, "%d\n", pid);
- X len = strlen(buf);
- openloop:
- X if ((fd = open(tempname, O_RDWR|O_CREAT|O_EXCL, 0644)) < 0) {
- X switch(errno) {
- X case EEXIST:
- X dprintf("%s: file %s exists already.\n",
- X Pname, tempname);
- X if (unlink(tempname) < 0) {
- X fprintf(stderr, "%s: unlink(%s): %s\n",
- X Pname, tempname, errmsg(errno));
- X return((char *)NULL);
- X }
- X /*
- X ** Further profanity
- X */
- X goto openloop;
- X default:
- X fprintf(stderr, "%s: open(%s): %s\n",
- X Pname, tempname, errmsg(errno));
- X return((char *)NULL);
- X }
- X }
- X
- X /*
- X ** Write the PID into the temporary file before attempting to link
- X ** to the actual lock file. That way we have a valid lock the instant
- X ** the link succeeds.
- X */
- X if (write(fd, buf, len) < 0) {
- X fprintf(stderr, "%s: write(%s,%d): %s\n",
- X Pname, tempname, pid, errmsg(errno));
- X (void) close(fd);
- X return((char *)NULL);
- X }
- X (void) close(fd);
- X return(tempname);
- X}
- END_OF_FILE
- if test 6278 -ne `wc -c <'./xmit/shlock.c'`; then
- echo shar: \"'./xmit/shlock.c'\" unpacked with wrong size!
- fi
- # end of './xmit/shlock.c'
- fi
- echo shar: End of archive 5 \(of 9\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-